import onnx
from onnx import helper
from onnx import TensorProto
import numpy as np

def make_conv():
    weight_shape = [64,3,7,7]
    input_shape = [64,3,224,224]
    output_shape = [64,64,112,112]

    X = helper.make_tensor_value_info('X', TensorProto.FLOAT, input_shape)
    
    weight = np.random.ranf(64*3*7*7).astype(np.float32)
    W = helper.make_tensor('W', TensorProto.FLOAT,weight_shape, weight)
    
    Y = helper.make_tensor_value_info('Y', TensorProto.FLOAT, output_shape)
    
    node_def = helper.make_node(
        'Conv', # node name
        ['X', 'W'],
        ['Y'], # outputs
        dilations = [1,1],
        group = 1,
        kernel_shape = [7,7],
        pads = [3,3,3,3],
        strides=[2,2]
        )

    graph_def = helper.make_graph(
        [node_def],
        'test_conv_node',
        [X], # graph inputs
        [Y], # graph outputs
        initializer=[W],
    )
    
    mode_def = helper.make_model(graph_def, opset_imports=[helper.make_opsetid("", 14)])
    mode_def.ir_version = 7
    onnx.checker.check_model(mode_def)
    onnx.save(mode_def, "./conv_batch_64.onnx")

def make_conv2():
    weight_shape = [1,3,7,7]
    input_shape = [1,3,32,32]
    output_shape = [1,1,16,16]

    X = helper.make_tensor_value_info('X', TensorProto.FLOAT, input_shape)
    
    weight = np.random.ranf(1*3*7*7).astype(np.float32)
    W = helper.make_tensor('W', TensorProto.FLOAT,weight_shape, weight)
    
    Y = helper.make_tensor_value_info('Y', TensorProto.FLOAT, output_shape)
    
    node_def = helper.make_node(
        'Conv', # node name
        ['X', 'W'],
        ['Y'], # outputs
        dilations = [1,1],
        group = 1,
        kernel_shape = [7,7],
        pads = [3,3,3,3],
        strides=[2,2]
        )

    graph_def = helper.make_graph(
        [node_def],
        'test_conv_node',
        [X], # graph inputs
        [Y], # graph outputs
        initializer=[W],
    )
    
    mode_def = helper.make_model(graph_def, opset_imports=[helper.make_opsetid("", 11)])
    mode_def.ir_version = 7
    onnx.checker.check_model(mode_def)
    onnx.save(mode_def, "./conv2.onnx")

def make_conv3():
    weight_shape = [1,3,5,7]
    input_shape = [1,3,32,32]
    output_shape = [1,1,18,12]

    X = helper.make_tensor_value_info('X', TensorProto.FLOAT, input_shape)
    
    weight = np.random.ranf(1*3*5*7).astype(np.float32)
    W = helper.make_tensor('W', TensorProto.FLOAT,weight_shape, weight)
    
    Y = helper.make_tensor_value_info('Y', TensorProto.FLOAT, output_shape)
    
    node_def = helper.make_node(
        'Conv', # node name
        ['X', 'W'],
        ['Y'], # outputs
        dilations = [1,1],
        group = 1,
        kernel_shape = [5,7],
        pads = [3,3,5,5],
        strides=[2,3]
        )

    graph_def = helper.make_graph(
        [node_def],
        'test_conv_node',
        [X], # graph inputs
        [Y], # graph outputs
        initializer=[W],
    )
    
    mode_def = helper.make_model(graph_def, opset_imports=[helper.make_opsetid("", 11)])
    mode_def.ir_version = 7
    onnx.checker.check_model(mode_def)
    onnx.save(mode_def, "./conv3.onnx")

def make_add():
    input_shape = [3,4,5]
    output_shape = [3,4,5]

    X = helper.make_tensor_value_info('X', TensorProto.FLOAT, input_shape)
    Y = helper.make_tensor_value_info('Y', TensorProto.FLOAT, input_shape)
    Z = helper.make_tensor_value_info('Z', TensorProto.FLOAT, output_shape)
    
    node_def = helper.make_node(
        'Add', # node name
        ['X', 'Y'],
        ['Z']  # outputs
        )

    graph_def = helper.make_graph(
        [node_def],
        'test_add_node',
        [X, Y], # graph inputs
        [Z], # graph outputs
    )
    
    mode_def = helper.make_model(graph_def, opset_imports=[helper.make_opsetid("", 14)])
    mode_def.ir_version = 7
    onnx.checker.check_model(mode_def)
    onnx.save(mode_def, "./add.onnx")

def make_add_max():
    input_shape = [3,4,5]
    output_shape = [3,4,5]

    X = helper.make_tensor_value_info('X', TensorProto.FLOAT, input_shape)
    Y = helper.make_tensor_value_info('Y', TensorProto.FLOAT, input_shape)
    Z = helper.make_tensor_value_info('Z', TensorProto.FLOAT, output_shape)

    N = helper.make_tensor_value_info('N', TensorProto.FLOAT, output_shape)
    
    node_add = helper.make_node(
        'Add', # node name
        ['X', 'Y'],
        ['Z']  # outputs
        )

    node_max = helper.make_node(
        'Max', # node name
        ['Z'],
        ['N']  # outputs
        )    

    graph_def = helper.make_graph(
        [node_add, node_max],
        'test_add_mode',
        [X, Y], # graph inputs
        [N], # graph outputs
    )
    
    mode_def = helper.make_model(graph_def, opset_imports=[helper.make_opsetid("", 14)])
    mode_def.ir_version = 7
    onnx.checker.check_model(mode_def)
    onnx.save(mode_def, "./add_max.onnx")

def make_add_max_hardmax():
    input_shape = [3,4,5]
    output_shape = [3,4,5]

    X = helper.make_tensor_value_info('X', TensorProto.FLOAT, input_shape)
    Y = helper.make_tensor_value_info('Y', TensorProto.FLOAT, input_shape)
    Z = helper.make_tensor_value_info('Z', TensorProto.FLOAT, output_shape)

    N = helper.make_tensor_value_info('N', TensorProto.FLOAT, output_shape)

    H = helper.make_tensor_value_info('H', TensorProto.FLOAT, output_shape)
    
    node_add = helper.make_node(
        'Add', # node name
        ['X', 'Y'],
        ['Z']  # outputs
        )

    node_max = helper.make_node(
        'Max', # node name
        ['Z'],
        ['N']  # outputs
        )

    node_hardmax = helper.make_node(
        'Hardmax', # node name
        ['N'],
        ['H']  # outputs
        )         

    graph_def = helper.make_graph(
        [node_add, node_max, node_hardmax],
        'test_add_max_hardmax_mode',
        [X, Y], # graph inputs
        [H], # graph outputs
    )
    
    mode_def = helper.make_model(graph_def, opset_imports=[helper.make_opsetid("", 14)])
    mode_def.ir_version = 7
    onnx.checker.check_model(mode_def)
    onnx.save(mode_def, "./add_max_hardmax.onnx")

def make_multi():
    input_shape = [3,4,5]
    output_shape = [3,4,5]

    X = helper.make_tensor_value_info('X', TensorProto.FLOAT, input_shape)
    Y = helper.make_tensor_value_info('Y', TensorProto.FLOAT, input_shape)
    Z = helper.make_tensor_value_info('Z', TensorProto.FLOAT, output_shape)

    N = helper.make_tensor_value_info('N', TensorProto.FLOAT, output_shape)
    M = helper.make_tensor_value_info('M', TensorProto.FLOAT, input_shape)

    Q = helper.make_tensor_value_info('Q', TensorProto.FLOAT, output_shape)
    H = helper.make_tensor_value_info('H', TensorProto.FLOAT, output_shape)
    
    node_add = helper.make_node(
        'Add', # node name
        ['X', 'Y'],
        ['Z']  # outputs
        )

    node_max = helper.make_node(
        'Max', # node name
        ['Z'],
        ['N']  # outputs
        )

    node_add2 = helper.make_node(
        'Add', # node name
        ['N', 'N'],
        ['Q']  # outputs
        ) 

    node_max2 = helper.make_node(
        'Max', # node name
        ['Q'],
        ['M']  # outputs
        )       

    node_hardmax = helper.make_node(
        'Hardmax', # node name
        ['M'],
        ['H']  # outputs
        )         

    graph_def = helper.make_graph(
        [node_add, node_max, node_add2, node_max2, node_hardmax],
        'test_make_multi',
        [X, Y], # graph inputs
        [H], # graph outputs
    )
    
    mode_def = helper.make_model(graph_def, opset_imports=[helper.make_opsetid("", 14)])
    mode_def.ir_version = 7
    onnx.checker.check_model(mode_def)
    onnx.save(mode_def, "./test_multi.onnx")

def make_mish():
    graph = helper.make_graph(
        [
           helper.make_node('Mish', ['x'], ['y'], 'mish', domain='') 
        ],
        'mish',
        [
            helper.make_tensor_value_info('x', TensorProto.FLOAT, ['h', 'w'])
        ],
        [
            helper.make_tensor_value_info('y', TensorProto.FLOAT, ['h', 'w'])
        ],
        [

        ]
    )
    
    model = helper.make_model(graph)
    onnx.save(model, './mish.onnx')

def make_custom_op_1():
    graph = helper.make_graph(
        [
           helper.make_node('TestOp1', ['x', 'y'], ['z'], 'test1', domain='') 
        ],
        'test1',
        [
            helper.make_tensor_value_info('x', TensorProto.FLOAT, [2, 2]),
            helper.make_tensor_value_info('y', TensorProto.FLOAT, [2, 2])
        ],
        [
            helper.make_tensor_value_info('z', TensorProto.FLOAT, [2, 2])
        ],
        [

        ]
    )
    
    model = helper.make_model(graph)
    onnx.save(model, './cop1.onnx')

def make_preproc():
    '''    
    graph = helper.make_graph(
        [
           helper.make_node('PreProc', ['x', 'y'], ['z'], 'test1', domain='') 
        ],
        'test1',
        [
            helper.make_tensor_value_info('x', TensorProto.FLOAT, [2, 2]),
            helper.make_tensor_value_info('y', TensorProto.FLOAT, [2, 2])
        ],
        [
            helper.make_tensor_value_info('z', TensorProto.FLOAT, [2, 2])
        ],
        [

        ]
    )
    '''
    const_mean = onnx.helper.make_tensor(name='const_mean',
                        data_type=onnx.TensorProto.UINT8,
                        dims=[3],
                        vals=[128, 128, 128])

    #graph.initializer.append(const_mean)

    const_std = onnx.helper.make_tensor(name='const_std',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[3],
                        vals=[0.00784, 0.00784, 0.00784])

    #graph.initializer.append(const_std)

    const_resize = onnx.helper.make_tensor(name='const_resize',
                        data_type=onnx.TensorProto.INT32,
                        dims=[4],
                        vals=[375, 500, 375, 500])

    #graph.initializer.append(const_resize)

    const_crop = onnx.helper.make_tensor(name='const_crop',
                        data_type=onnx.TensorProto.INT32,
                        dims=[4],
                        vals=[-1,-1,-1,-1])

    const_control = onnx.helper.make_tensor(name='const_control',
                        data_type=onnx.TensorProto.INT32,
                        dims=[5],
                        vals=[0, 0, 0,0, 0])   #rgb2bgr, crop_first, norm_first                 

    #graph.initializer.append(const_crop)

    #x = helper.make_tensor_value_info('x', TensorProto.UINT8, [1, 3, 512, 512])
    #y = helper.make_tensor_value_info('y', TensorProto.FLOAT, [1, 3, 224, 224])     

    x = helper.make_tensor_value_info('x', TensorProto.UINT8, [1, 3, 375, 500])
    y = helper.make_tensor_value_info('y', TensorProto.FLOAT, [1, 3, 375, 500])      

    pre_process_node = onnx.helper.make_node(
                    'PreProc',
                    name='preprocess',
                    inputs=['x', 'const_std', 'const_mean', 'const_resize','const_crop', 'const_control'],
                    outputs=['y'],
                    domain='com.metax-tech')

    graph = helper.make_graph(
        [pre_process_node],
        'preproc',
        [
            x
        ],
        [
            y
        ],
        [
            const_std,
            const_mean,
            const_resize,
            const_crop,
            const_control
        ]
    )                

    model = helper.make_model(graph)
    
    op_set = model.opset_import.add()
    op_set.domain = 'com.metax-tech'
    op_set.version = 1

    onnx.save(model, './p1.onnx')

def make_preproc_1():
    '''    
    graph = helper.make_graph(
        [
           helper.make_node('PreProc', ['x', 'y'], ['z'], 'test1', domain='') 
        ],
        'test1',
        [
            helper.make_tensor_value_info('x', TensorProto.FLOAT, [2, 2]),
            helper.make_tensor_value_info('y', TensorProto.FLOAT, [2, 2])
        ],
        [
            helper.make_tensor_value_info('z', TensorProto.FLOAT, [2, 2])
        ],
        [

        ]
    )
    '''
    const_mean = onnx.helper.make_tensor(name='const_mean',
                        data_type=onnx.TensorProto.UINT8,
                        dims=[3],
                        vals=[32, 32, 32])

    const_std = onnx.helper.make_tensor(name='const_std',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[3],
                        vals=[1.0/127.5, 1.0/127.5, 1.0/127.5])

    x = helper.make_tensor_value_info('x', TensorProto.UINT8, [1, 3, 5, 5])
    y = helper.make_tensor_value_info('y', TensorProto.FLOAT, [1, 3, 5, 5])      

    pre_process_node = onnx.helper.make_node(
                    'PreProc',
                    name='preprocess',
                    inputs=['x', 'const_std', 'const_mean'],
                    outputs=['y'],
                    domain='')

    graph = helper.make_graph(
        [pre_process_node],
        'preproc',
        [
            x
        ],
        [
            y
        ],
        [
            const_std,
            const_mean
        ]
    )                

    model = helper.make_model(graph)
    onnx.save(model, './preproc1.onnx')

def make_preproc_2():
    const_mean = onnx.helper.make_tensor(name='const_mean',
                        data_type=onnx.TensorProto.UINT8,
                        dims=[3],
                        vals=[30, 40, 50])

    #graph.initializer.append(const_mean)

    const_std = onnx.helper.make_tensor(name='const_std',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[3],
                        vals=[0.001, 0.002, 0.003])

    #graph.initializer.append(const_std)

    const_resize = onnx.helper.make_tensor(name='const_resize',
                        data_type=onnx.TensorProto.INT32,
                        dims=[2],
                        vals=[-1, -1])

    #graph.initializer.append(const_resize)

    const_crop = onnx.helper.make_tensor(name='const_crop',
                        data_type=onnx.TensorProto.INT32,
                        dims=[4],
                        vals=[-1, -1, -1, -1])

    const_transpose_cropfirst = onnx.helper.make_tensor(name='const_transpose_cropfirst',
                        data_type=onnx.TensorProto.INT32,
                        dims=[2],
                        vals=[1,1])                    

    #graph.initializer.append(const_crop)

    x = helper.make_tensor_value_info('x', TensorProto.UINT8, [1, 3, 720, 576])
    y = helper.make_tensor_value_info('y', TensorProto.FLOAT, [1, 3, 720, 576])      

    pre_process_node = onnx.helper.make_node(
                    'PreProc',
                    name='preprocess',
                    inputs=['x', 'const_std', 'const_mean', 'const_resize','const_crop', 'const_transpose_cropfirst'],
                    outputs=['y'],
                    domain='')

    graph = helper.make_graph(
        [pre_process_node],
        'preproc',
        [
            x
        ],
        [
            y
        ],
        [
            const_std,
            const_mean,
            const_resize,
            const_crop,
            const_transpose_cropfirst
        ]
    )                

    model = helper.make_model(graph)
    onnx.save(model, './preproc2.onnx')

def make_multi_test():
    input_shape = [1, 3, 375, 500]
    split_shape = [1, 1, 375, 500]

    output_shape = [1, 3, 375, 500]

    const_zp = onnx.helper.make_tensor(name='const_zp',
                        data_type=onnx.TensorProto.UINT8,
                        dims=(),
                        vals=[128])

    const_scale = onnx.helper.make_tensor(name='const_scale',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=(),
                        vals=[0.00784])

    X = helper.make_tensor_value_info('X', TensorProto.UINT8, input_shape)

    A = helper.make_tensor_value_info('A', TensorProto.UINT8, split_shape)
    B = helper.make_tensor_value_info('B', TensorProto.UINT8, split_shape)
    C = helper.make_tensor_value_info('C', TensorProto.UINT8, split_shape)

    D = helper.make_tensor_value_info('D', TensorProto.FLOAT, split_shape)
    E = helper.make_tensor_value_info('E', TensorProto.FLOAT, split_shape)
    F = helper.make_tensor_value_info('F', TensorProto.FLOAT, split_shape)

    Y = helper.make_tensor_value_info('Y', TensorProto.FLOAT, output_shape)

    node_split = helper.make_node(
        'Split', # node name
        ['X'],
        ['A', 'B', 'C'],  # outputs
        axis=1
        )

    node_dq1 = helper.make_node(
        'DequantizeLinear', # node name
        ['A', 'const_scale', 'const_zp'],
        ['D']  # outputs
        )

    node_dq2 = helper.make_node(
        'DequantizeLinear', # node name
        ['B', 'const_scale', 'const_zp'],
        ['E']  # outputs
        )

    node_dq3 = helper.make_node(
        'DequantizeLinear', # node name
        ['C', 'const_scale', 'const_zp'],
        ['F']  # outputs
        )    
###############

    node_concat = helper.make_node(
        'Concat', # node name
        ['D', 'E', 'F'],
        ['Y'],  # outputs
        axis=1
        )       

    graph_def = helper.make_graph(
        [node_split, node_dq1, node_dq2, node_dq3, node_concat],
        'test_make_multi',
        [X], # graph inputs
        [Y], # graph outputs
        [const_zp, const_scale],
    )
    
    mode_def = helper.make_model(graph_def, opset_imports=[helper.make_opsetid("", 11)])
    mode_def.ir_version = 7
    onnx.checker.check_model(mode_def)
    onnx.save(mode_def, "./test_multi.onnx")

def make_p3():
    input_shape = [1, 3, 375, 500]
    split_shape = [1, 1, 375, 500]

    X = helper.make_tensor_value_info('X', TensorProto.UINT8, input_shape)

    A = helper.make_tensor_value_info('A', TensorProto.UINT8, split_shape)
    B = helper.make_tensor_value_info('B', TensorProto.UINT8, split_shape)
    C = helper.make_tensor_value_info('C', TensorProto.UINT8, split_shape)

    node_split = helper.make_node(
        'Split', # node name
        ['X'],
        ['A', 'B', 'C'],  # outputs
        axis=1
        )

    graph_def = helper.make_graph(
        [node_split],
        'test_make_multi',
        [X], # graph inputs
        [A, B, C]
    )
    
    mode_def = helper.make_model(graph_def, opset_imports=[helper.make_opsetid("", 11)])
    mode_def.ir_version = 7
    onnx.checker.check_model(mode_def)
    onnx.save(mode_def, "./p3.onnx")

def make_p4():
    input_shape = [1, 3, 375, 500]
    split_shape = [1, 1, 375, 500]

    output_shape = [1, 3, 375, 500]

    const_zp = onnx.helper.make_tensor(name='const_zp',
                        data_type=onnx.TensorProto.UINT8,
                        dims=(),
                        vals=[127])

    const_scale = onnx.helper.make_tensor(name='const_scale',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=(),
                        vals=[0.00784])

    X = helper.make_tensor_value_info('X', TensorProto.UINT8, input_shape)

    A = helper.make_tensor_value_info('A', TensorProto.UINT8, split_shape)
    B = helper.make_tensor_value_info('B', TensorProto.UINT8, split_shape)
    C = helper.make_tensor_value_info('C', TensorProto.UINT8, split_shape)

    D = helper.make_tensor_value_info('D', TensorProto.FLOAT, split_shape)
    E = helper.make_tensor_value_info('E', TensorProto.FLOAT, split_shape)
    F = helper.make_tensor_value_info('F', TensorProto.FLOAT, split_shape)

    node_split = helper.make_node(
        'Split', # node name
        ['X'],
        ['A', 'B', 'C'],  # outputs
        axis=1
        )

    node_dq1 = helper.make_node(
        'DequantizeLinear', # node name
        ['A', 'const_scale', 'const_zp'],
        ['D']  # outputs
        )

    node_dq2 = helper.make_node(
        'DequantizeLinear', # node name
        ['B', 'const_scale', 'const_zp'],
        ['E']  # outputs
        )

    node_dq3 = helper.make_node(
        'DequantizeLinear', # node name
        ['C', 'const_scale', 'const_zp'],
        ['F']  # outputs
        )    
###############

    graph_def = helper.make_graph(
        [node_split, node_dq1, node_dq2, node_dq3],
        'test_make_multi',
        [X], # graph inputs
        [D, E, F], # graph outputs
        [const_zp, const_scale],
    )
    
    mode_def = helper.make_model(graph_def, opset_imports=[helper.make_opsetid("", 11)])
    mode_def.ir_version = 7
    onnx.checker.check_model(mode_def)
    onnx.save(mode_def, "./p4.onnx")

def make_p6():
    input_shape = [1, 1, 375, 500]
    split_shape = [1, 1, 375, 500]

    output_shape = [1, 1, 375, 500]

    const_zp = onnx.helper.make_tensor(name='const_zp',
                        data_type=onnx.TensorProto.UINT8,
                        dims=(),
                        vals=[128])

    const_scale = onnx.helper.make_tensor(name='const_scale',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=(),
                        vals=[0.00784])

    X = helper.make_tensor_value_info('X', TensorProto.UINT8, input_shape)

    A = helper.make_tensor_value_info('A', TensorProto.UINT8, split_shape)

    D = helper.make_tensor_value_info('D', TensorProto.FLOAT, split_shape)


    node_split = helper.make_node(
        'Split', # node name
        ['X'],
        ['A'],  # outputs
        axis=1
        )

    node_dq1 = helper.make_node(
        'DequantizeLinear', # node name
        ['A', 'const_scale', 'const_zp'],
        ['D']  # outputs
        ) 
###############

    graph_def = helper.make_graph(
        [node_split, node_dq1],
        'test_make_multi',
        [X], # graph inputs
        [D], # graph outputs
        [const_zp, const_scale],
    )
    
    mode_def = helper.make_model(graph_def, opset_imports=[helper.make_opsetid("", 11)])
    mode_def.ir_version = 7
    onnx.checker.check_model(mode_def)
    onnx.save(mode_def, "./p6.onnx")

def make_p7():
    input_shape = [1, 1, 375, 500]
    split_shape = [1, 1, 375, 500]

    output_shape = [1, 1, 375, 500]

    const_zp = onnx.helper.make_tensor(name='const_zp',
                        data_type=onnx.TensorProto.INT8,
                        dims=(),
                        vals=[128])

    const_scale = onnx.helper.make_tensor(name='const_scale',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=(),
                        vals=[0.00784])

    X = helper.make_tensor_value_info('X', TensorProto.INT8, input_shape)

    A = helper.make_tensor_value_info('A', TensorProto.INT8, split_shape)

    D = helper.make_tensor_value_info('D', TensorProto.FLOAT, split_shape)


    node_split = helper.make_node(
        'Split', # node name
        ['X'],
        ['A'],  # outputs
        axis=1
        )

    node_dq1 = helper.make_node(
        'DequantizeLinear', # node name
        ['A', 'const_scale', 'const_zp'],
        ['D']  # outputs
        ) 
###############

    graph_def = helper.make_graph(
        [node_split, node_dq1],
        'test_make_multi',
        [X], # graph inputs
        [D], # graph outputs
        [const_zp, const_scale],
    )
    
    mode_def = helper.make_model(graph_def, opset_imports=[helper.make_opsetid("", 11)])
    mode_def.ir_version = 7
    onnx.checker.check_model(mode_def)
    onnx.save(mode_def, "./p7.onnx")

def make_p8():
    input_shape = [1, 1, 375, 500]
    split_shape = [1, 1, 375, 500]

    output_shape = [1, 1, 375, 500]

    X = helper.make_tensor_value_info('X', TensorProto.UINT8, input_shape)

    A = helper.make_tensor_value_info('A', TensorProto.UNT8, split_shape)

    D = helper.make_tensor_value_info('D', TensorProto.FLOAT, split_shape)

    node_split = helper.make_node(
        'Split', # node name
        ['X'],
        ['A'],  # outputs
        axis=1
        )

    node_dq1 = helper.make_node(
        'Cast', # node name
        ['A'],
        ['D'],  # outputs
        to=1
        ) 
###############

    graph_def = helper.make_graph(
        [node_split, node_dq1],
        'test_make_multi',
        [X], # graph inputs
        [D]# graph outputs
    )
    
    mode_def = helper.make_model(graph_def, opset_imports=[helper.make_opsetid("", 11)])
    mode_def.ir_version = 7
    onnx.checker.check_model(mode_def)
    onnx.save(mode_def, "./p8.onnx")

def make_dq():
    input_shape = [1, 1, 375, 500]
    output_shape = [1, 1, 375, 500]

    const_zp = onnx.helper.make_tensor(name='const_zp',
                        data_type=onnx.TensorProto.UINT8,
                        dims=(),
                        vals=[128])

    const_scale = onnx.helper.make_tensor(name='const_scale',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=(),
                        vals=[0.00784])

    X = helper.make_tensor_value_info('X', TensorProto.UINT8, input_shape)
    Y = helper.make_tensor_value_info('Y', TensorProto.FLOAT, output_shape)

    node_dq1 = helper.make_node(
        'DequantizeLinear', # node name
        ['X', 'const_scale', 'const_zp'],
        ['Y']  # outputs
        )

  
    graph_def = helper.make_graph(
        [node_dq1],
        'test_make_multi',
        [X], # graph inputs
        [Y], # graph outputs
        [const_zp, const_scale],
    )
    
    mode_def = helper.make_model(graph_def, opset_imports=[helper.make_opsetid("", 11)])
    mode_def.ir_version = 7
    onnx.checker.check_model(mode_def)
    onnx.save(mode_def, "./dq.onnx")

def make_n1():
    input_shape = [1, 3, 375, 500]
    split_shape = [1, 1, 375, 500]

    output_shape = [1, 3, 375, 500]

    const_zp = onnx.helper.make_tensor(name='const_zp',
                        data_type=onnx.TensorProto.UINT8,
                        dims=(),
                        vals=[128])

    const_scale = onnx.helper.make_tensor(name='const_scale',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=(),
                        vals=[0.00784])

    X = helper.make_tensor_value_info('X', TensorProto.UINT8, input_shape)

    AA = helper.make_tensor_value_info('AA', TensorProto.UINT8, split_shape)
    BB = helper.make_tensor_value_info('BB', TensorProto.UINT8, split_shape)
    CC = helper.make_tensor_value_info('CC', TensorProto.UINT8, split_shape)

    D = helper.make_tensor_value_info('D', TensorProto.UINT8, split_shape)
    E = helper.make_tensor_value_info('E', TensorProto.UINT8, split_shape)
    F = helper.make_tensor_value_info('F', TensorProto.UINT8, split_shape)

    L = helper.make_tensor_value_info('L', TensorProto.FLOAT, split_shape)
    M = helper.make_tensor_value_info('M', TensorProto.FLOAT, split_shape)
    N = helper.make_tensor_value_info('N', TensorProto.FLOAT, split_shape)

    O = helper.make_tensor_value_info('O', TensorProto.FLOAT, split_shape)
    P = helper.make_tensor_value_info('P', TensorProto.FLOAT, split_shape)
    Q = helper.make_tensor_value_info('Q', TensorProto.FLOAT, split_shape)

    Y = helper.make_tensor_value_info('Y', TensorProto.FLOAT, output_shape)

    node_split = helper.make_node(
        'Split', # node name
        ['X'],
        ['AA', 'BB', 'CC'],  # outputs
        axis=1,
        name='split_'
        )

    node_dq1 = helper.make_node(
        'Sub', # node name
        ['AA', 'const_zp'],
        ['D'],  # outputs
        name='sub1_'
        )

    node_dq2 = helper.make_node(
        'Sub', # node name
        ['BB', 'const_zp'],
        ['E'],  # outputs
        name='sub2_'
        )

    node_dq3 = helper.make_node(
        'Sub', # node name
        ['CC', 'const_zp'],
        ['F'],  # outputs
        name='sub3_'
        )    
###############
    node_cast1 = helper.make_node(
        'Cast', # node name
        ['D'],
        ['L'],  # outputs
        to=1
        )

    node_cast2 = helper.make_node(
        'Cast', # node name
        ['E'],
        ['M'],  # outputs
        to=1
        )  

    node_cast3 = helper.make_node(
        'Cast', # node name
        ['F'],
        ['N'],  # outputs
        to=1
        )      
#########################
    node_mul1 = helper.make_node(
        'Mul', # node name
        ['L', 'const_scale'],
        ['O']  # outputs
        )

    node_mul2 = helper.make_node(
        'Mul', # node name
        ['M', 'const_scale'],
        ['P'] # outputs
        )  

    node_mul3 = helper.make_node(
        'Mul', # node name
        ['N', 'const_scale'],
        ['Q']  # outputs
        )      

    node_concat = helper.make_node(
        'Concat', # node name
        ['O', 'P', 'Q'],
        ['Y'],  # outputs
        axis=1
        )       

    graph_def = helper.make_graph(
        [node_split, node_dq1, node_dq2, node_dq3, node_cast1, node_cast2, node_cast3, node_mul1, node_mul2, node_mul3, node_concat],
        'test_make_multi',
        [X], # graph inputs
        [Y], # graph outputs
        [const_zp, const_scale],
    )
    
    mode_def = helper.make_model(graph_def, opset_imports=[helper.make_opsetid("", 11)])
    mode_def.ir_version = 7
    onnx.checker.check_model(mode_def)
    onnx.save(mode_def, "./n3.onnx")

def make_n2():
    input_shape = [1, 3, 375, 500]
    split_shape = [1, 1, 375, 500]

    output_shape = [1, 3, 375, 500]

    X = helper.make_tensor_value_info('X', TensorProto.UINT8, input_shape)

    A = helper.make_tensor_value_info('A', TensorProto.FLOAT16, split_shape)
    B = helper.make_tensor_value_info('B', TensorProto.FLOAT16, split_shape)
    C = helper.make_tensor_value_info('C', TensorProto.FLOAT16, split_shape)

    node_split = helper.make_node(
        'Split', # node name
        ['X'],
        ['A', 'B', 'C'],  # outputs
        axis=1
        )

    graph_def = helper.make_graph(
        [node_split],
        'test_make_multi',
        [X], # graph inputs
        [A, B, C] # graph outputs
    )
    
    mode_def = helper.make_model(graph_def, opset_imports=[helper.make_opsetid("", 11)])
    mode_def.ir_version = 7
    onnx.checker.check_model(mode_def)
    onnx.save(mode_def, "./n2.onnx")

def make_nn1():
    const_mean_r = onnx.helper.make_tensor(name='const_mean_r',
                        data_type=onnx.TensorProto.UINT8,
                        dims=[1],
                        vals=[128])

    const_mean_g = onnx.helper.make_tensor(name='const_mean_g',
                        data_type=onnx.TensorProto.UINT8,
                        dims=[1],
                        vals=[128])

    const_mean_b = onnx.helper.make_tensor(name='const_mean_b',
                        data_type=onnx.TensorProto.UINT8,
                        dims=[1],
                        vals=[128])


    #graph.initializer.append(const_mean)

    const_std_r = onnx.helper.make_tensor(name='const_std_r',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[0.00784])

    const_std_g = onnx.helper.make_tensor(name='const_std_g',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[0.00784])

    const_std_b = onnx.helper.make_tensor(name='const_std_b',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[0.00784])                    

    #graph.initializer.append(const_std)

    const_resize = onnx.helper.make_tensor(name='const_resize',
                        data_type=onnx.TensorProto.INT32,
                        dims=[4],
                        vals=[256, 256, 224, 224])

    #graph.initializer.append(const_resize)

    const_crop = onnx.helper.make_tensor(name='const_crop',
                        data_type=onnx.TensorProto.INT32,
                        dims=[4],
                        vals=[-1,-1,-1,-1])

    const_control = onnx.helper.make_tensor(name='const_control',
                        data_type=onnx.TensorProto.INT32,
                        dims=[5],
                        vals=[1, 0, 0,0, 1])   #rgb2bgr, crop_first, norm_first                 

    #graph.initializer.append(const_crop)

    #x = helper.make_tensor_value_info('x', TensorProto.UINT8, [1, 3, 512, 512])
    #y = helper.make_tensor_value_info('y', TensorProto.FLOAT, [1, 3, 224, 224])     

    x = helper.make_tensor_value_info('x', TensorProto.UINT8, [1, 3, 512, 512])
    y = helper.make_tensor_value_info('y', TensorProto.FLOAT, [1, 3, 224, 224])      

    pre_process_node = onnx.helper.make_node(
                    'PreProc',
                    name='preprocess',
                    inputs=['x', 'const_std_r', 'const_std_g', 'const_std_b', 'const_mean_r', 'const_mean_g', 'const_mean_b','const_resize','const_crop', 'const_control'],
                    outputs=['y'],
                    domain='com.metax-tech')

    graph = helper.make_graph(
        [pre_process_node],
        'preproc',
        [
            x
        ],
        [
            y
        ],
        [
            const_std_r,
            const_std_g,
            const_std_b,
            const_mean_r,
            const_mean_g,
            const_mean_b,
            const_resize,
            const_crop,
            const_control
        ]
    )                

    model = helper.make_model(graph)
    
    op_set = model.opset_import.add()
    op_set.domain = 'com.metax-tech'
    op_set.version = 1

    onnx.save(model, './nn1.onnx')

def make_slice():
    input_shape = [32]
    output_shape = [24]

    X = helper.make_tensor_value_info('X', TensorProto.FLOAT, input_shape)
    
    const_starts = onnx.helper.make_tensor(name='const_starts',
                        data_type=onnx.TensorProto.INT64,
                        dims=[1],
                        vals=[0])

    const_ends = onnx.helper.make_tensor(name='const_ends',
                        data_type=onnx.TensorProto.INT64,
                        dims=[1],
                        vals=[24])
    
    Y = helper.make_tensor_value_info('Y', TensorProto.FLOAT, output_shape)
    
    node_def = helper.make_node(
        'Slice', # node name
        ['X', 'const_starts', 'const_ends'],
        ['Y'], # outputs
        )

    graph_def = helper.make_graph(
        [node_def],
        'test_slice',
        [X], # graph inputs
        [Y], # graph outputs
        initializer=[const_starts, const_ends],
    )
    
    mode_def = helper.make_model(graph_def, opset_imports=[helper.make_opsetid("", 11)])
    mode_def.ir_version = 7
    onnx.checker.check_model(mode_def)
    onnx.save(mode_def, "./slice.onnx")

def make_tile():
    input_shape = [1,32]
    output_shape = [5,32]

    X = helper.make_tensor_value_info('X', TensorProto.FLOAT, input_shape)
    
    const_repeats = onnx.helper.make_tensor(name='const_repeats',
                        data_type=onnx.TensorProto.INT64,
                        dims=[2],
                        vals=[5, 1])

    Y = helper.make_tensor_value_info('Y', TensorProto.FLOAT, output_shape)
    
    node_def = helper.make_node(
        'Tile', # node name
        ['X', 'const_repeats'],
        ['Y'], # outputs
        )

    graph_def = helper.make_graph(
        [node_def],
        'test_tile',
        [X], # graph inputs
        [Y], # graph outputs
        initializer=[const_repeats],
    )
    
    mode_def = helper.make_model(graph_def, opset_imports=[helper.make_opsetid("", 11)])
    mode_def.ir_version = 7
    onnx.checker.check_model(mode_def)
    onnx.save(mode_def, "./tile.onnx")

def make_gather():
    input_shape = [3,4]
    output_shape = [1,2,4]

    X = helper.make_tensor_value_info('X', TensorProto.FLOAT, input_shape)
    
    const_indicates = onnx.helper.make_tensor(name='const_indicates',
                        data_type=onnx.TensorProto.INT64,
                        dims=[4,2],
                        vals=[0,1,1,2,2,1,1,0])

    Y = helper.make_tensor_value_info('Y', TensorProto.FLOAT, output_shape)
    
    node_def = helper.make_node(
        'Gather', # node name
        ['X', 'const_indicates'],
        ['Y'], # outputs
        axis=0,
        )

    graph_def = helper.make_graph(
        [node_def],
        'test_gather',
        [X], # graph inputs
        [Y], # graph outputs
        initializer=[const_indicates],
    )
    
    mode_def = helper.make_model(graph_def, opset_imports=[helper.make_opsetid("", 11)])
    mode_def.ir_version = 7
    onnx.checker.check_model(mode_def)
    onnx.save(mode_def, "./gather.onnx")

def make_reducemean():
    input_shape = [2, 3]
    output_shape = []

    X = helper.make_tensor_value_info('X', TensorProto.FLOAT, input_shape)

    Y = helper.make_tensor_value_info('Y', TensorProto.FLOAT, output_shape)
    
    node_def = helper.make_node(
        'ReduceMean', # node name
        ['X'],
        ['Y'], # outputs
        axes=[0, 1],
        keepdims=0,
    )

    graph_def = helper.make_graph(
        [node_def],
        'test_reducemean',
        [X], # graph inputs
        [Y], # graph outputs
    )
    
    mode_def = helper.make_model(graph_def, opset_imports=[helper.make_opsetid("", 11)])
    mode_def.ir_version = 7
    onnx.checker.check_model(mode_def)
    onnx.save(mode_def, "./reducemean.onnx")



def make_nn2a():
    const_mean_r = onnx.helper.make_tensor(name='const_mean_r',
                        data_type=onnx.TensorProto.UINT8,
                        dims=[1],
                        vals=[128])

    const_mean_g = onnx.helper.make_tensor(name='const_mean_g',
                        data_type=onnx.TensorProto.UINT8,
                        dims=[1],
                        vals=[128])

    const_mean_b = onnx.helper.make_tensor(name='const_mean_b',
                        data_type=onnx.TensorProto.UINT8,
                        dims=[1],
                        vals=[128])


    #graph.initializer.append(const_mean)

    const_std_r = onnx.helper.make_tensor(name='const_std_r',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[0.00784])

    const_std_g = onnx.helper.make_tensor(name='const_std_g',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[0.00784])

    const_std_b = onnx.helper.make_tensor(name='const_std_b',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[0.00784])                    

    #graph.initializer.append(const_std)

    const_resize = onnx.helper.make_tensor(name='const_resize',
                        data_type=onnx.TensorProto.INT32,
                        dims=[4],
                        vals=[375, 500, 375, 500])

    #graph.initializer.append(const_resize)

    const_crop = onnx.helper.make_tensor(name='const_crop',
                        data_type=onnx.TensorProto.INT32,
                        dims=[4],
                        vals=[0,0,375,500])

    const_control = onnx.helper.make_tensor(name='const_control',
                        data_type=onnx.TensorProto.INT32,
                        dims=[5],
                        vals=[0, 0, 0,0, 1])   #rgb2bgr, crop_first, norm_first                 

    #graph.initializer.append(const_crop)

    #x = helper.make_tensor_value_info('x', TensorProto.UINT8, [1, 3, 512, 512])
    #y = helper.make_tensor_value_info('y', TensorProto.FLOAT, [1, 3, 224, 224])     

    x = helper.make_tensor_value_info('x', TensorProto.UINT8, [1, 3, 375, 500])
    y = helper.make_tensor_value_info('y', TensorProto.FLOAT, [1, 3, 375, 500])      

    pre_process_node = onnx.helper.make_node(
                    'PreProc',
                    name='preprocess',
                    inputs=['x', 'const_std_r', 'const_std_g', 'const_std_b', 'const_mean_r', 'const_mean_g', 'const_mean_b','const_resize','const_crop', 'const_control'],
                    outputs=['y'],
                    domain='com.metax-tech')

    graph = helper.make_graph(
        [pre_process_node],
        'preproc',
        [
            x
        ],
        [
            y
        ],
        [
            const_std_r,
            const_std_g,
            const_std_b,
            const_mean_r,
            const_mean_g,
            const_mean_b,
            const_resize,
            const_crop,
            const_control
        ]
    )                

    model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 11)])
    
    op_set = model.opset_import.add()
    op_set.domain = 'com.metax-tech'
    op_set.version = 1

    onnx.save(model, './nn3a.onnx')

def make_nn4a():
    const_mean_r = onnx.helper.make_tensor(name='const_mean_r',
                        data_type=onnx.TensorProto.UINT8,
                        dims=[1],
                        vals=[0])

    const_mean_g = onnx.helper.make_tensor(name='const_mean_g',
                        data_type=onnx.TensorProto.UINT8,
                        dims=[1],
                        vals=[0])

    const_mean_b = onnx.helper.make_tensor(name='const_mean_b',
                        data_type=onnx.TensorProto.UINT8,
                        dims=[1],
                        vals=[0])


    #graph.initializer.append(const_mean)

    const_std_r = onnx.helper.make_tensor(name='const_std_r',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[1.0])

    const_std_g = onnx.helper.make_tensor(name='const_std_g',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[1.0])

    const_std_b = onnx.helper.make_tensor(name='const_std_b',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[1.0])                    

    #graph.initializer.append(const_std)

    const_resize = onnx.helper.make_tensor(name='const_resize',
                        data_type=onnx.TensorProto.INT32,
                        dims=[4],
                        vals=[375, 500, 375, 500])

    #graph.initializer.append(const_resize)

    const_crop = onnx.helper.make_tensor(name='const_crop',
                        data_type=onnx.TensorProto.INT32,
                        dims=[4],
                        vals=[0,0,375,500])

    const_control = onnx.helper.make_tensor(name='const_control',
                        data_type=onnx.TensorProto.INT32,
                        dims=[5],
                        vals=[1, 0, 0,0, 1])   #rgb2bgr, crop_first, norm_first                 

    #graph.initializer.append(const_crop)

    #x = helper.make_tensor_value_info('x', TensorProto.UINT8, [1, 3, 512, 512])
    #y = helper.make_tensor_value_info('y', TensorProto.FLOAT, [1, 3, 224, 224])     

    x = helper.make_tensor_value_info('x', TensorProto.UINT8, [1, 3, 375, 500])
    y = helper.make_tensor_value_info('y', TensorProto.FLOAT, [1, 3, 375, 500])      

    pre_process_node = onnx.helper.make_node(
                    'PreProc',
                    name='preprocess',
                    inputs=['x', 'const_std_r', 'const_std_g', 'const_std_b', 'const_mean_r', 'const_mean_g', 'const_mean_b','const_resize','const_crop', 'const_control'],
                    outputs=['y'],
                    domain='com.metax-tech')

    graph = helper.make_graph(
        [pre_process_node],
        'preproc',
        [
            x
        ],
        [
            y
        ],
        [
            const_std_r,
            const_std_g,
            const_std_b,
            const_mean_r,
            const_mean_g,
            const_mean_b,
            const_resize,
            const_crop,
            const_control
        ]
    )                

    model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 11)])
    
    op_set = model.opset_import.add()
    op_set.domain = 'com.metax-tech'
    op_set.version = 1

    onnx.save(model, './nn4a.onnx')

def make_add2():
    input_shape = [1,3,9,9]
    output_shape = [1,3,9,9]

    const_y = onnx.helper.make_tensor(name='const_y',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=(),
                        vals=[0.0])   #rgb2bgr, crop_first, norm_first   

    X = onnx.helper.make_tensor_value_info('X', TensorProto.FLOAT, input_shape)
    Z = onnx.helper.make_tensor_value_info('Z', TensorProto.FLOAT, output_shape)
    
    node_def = helper.make_node(
        'Add', # node name
        ['X', 'const_y'],
        ['Z']  # outputs
        )

    graph_def = helper.make_graph(
        [node_def],
        'test_add_node',
        [X], # graph inputs
        [Z], #  outputs
        [const_y],
    )
    
    mode_def = helper.make_model(graph_def, opset_imports=[helper.make_opsetid("", 11)])
    mode_def.ir_version = 7
    onnx.checker.check_model(mode_def)
    onnx.save(mode_def, "./add1.onnx")

def make_nn6a():
    const_mean_r = onnx.helper.make_tensor(name='const_mean_r',
                        data_type=onnx.TensorProto.UINT8,
                        dims=[1],
                        vals=[100])

    const_mean_g = onnx.helper.make_tensor(name='const_mean_g',
                        data_type=onnx.TensorProto.UINT8,
                        dims=[1],
                        vals=[100])

    const_mean_b = onnx.helper.make_tensor(name='const_mean_b',
                        data_type=onnx.TensorProto.UINT8,
                        dims=[1],
                        vals=[100])


    #graph.initializer.append(const_mean)

    const_std_r = onnx.helper.make_tensor(name='const_std_r',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[0.007])

    const_std_g = onnx.helper.make_tensor(name='const_std_g',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[0.007])

    const_std_b = onnx.helper.make_tensor(name='const_std_b',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[0.007])                    

    #graph.initializer.append(const_std)

    const_resize = onnx.helper.make_tensor(name='const_resize',
                        data_type=onnx.TensorProto.INT32,
                        dims=[4],
                        vals=[375, 500, 224, 224])

    #graph.initializer.append(const_resize)

    const_crop = onnx.helper.make_tensor(name='const_crop',
                        data_type=onnx.TensorProto.INT32,
                        dims=[4],
                        vals=[0,0,375,500])

    const_control = onnx.helper.make_tensor(name='const_control',
                        data_type=onnx.TensorProto.INT32,
                        dims=[5],
                        vals=[1, 0, 0, 0, 1])   #rgb2bgr, crop_first, norm_first                 

    #graph.initializer.append(const_crop)

    #x = helper.make_tensor_value_info('x', TensorProto.UINT8, [1, 3, 512, 512])
    #y = helper.make_tensor_value_info('y', TensorProto.FLOAT, [1, 3, 224, 224])     

    x = helper.make_tensor_value_info('x', TensorProto.UINT8, [1, 3, 375, 500])
    y = helper.make_tensor_value_info('y', TensorProto.FLOAT, [1, 3, 224, 224])      

    pre_process_node = onnx.helper.make_node(
                    'PreProc',
                    name='preprocess',
                    inputs=['x', 'const_std_r', 'const_std_g', 'const_std_b', 'const_mean_r', 'const_mean_g', 'const_mean_b','const_resize','const_crop', 'const_control'],
                    outputs=['y'],
                    domain='com.metax-tech')

    graph = helper.make_graph(
        [pre_process_node],
        'preproc',
        [
            x
        ],
        [
            y
        ],
        [
            const_std_r,
            const_std_g,
            const_std_b,
            const_mean_r,
            const_mean_g,
            const_mean_b,
            const_resize,
            const_crop,
            const_control
        ]
    )                

    model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 11)])
    
    op_set = model.opset_import.add()
    op_set.domain = 'com.metax-tech'
    op_set.version = 1

    onnx.save(model, './nn9a.onnx')

def make_nnaa():
    const_mean_r = onnx.helper.make_tensor(name='const_mean_r',
                        data_type=onnx.TensorProto.UINT8,
                        dims=[1],
                        vals=[44])

    const_mean_g = onnx.helper.make_tensor(name='const_mean_g',
                        data_type=onnx.TensorProto.UINT8,
                        dims=[1],
                        vals=[88])

    const_mean_b = onnx.helper.make_tensor(name='const_mean_b',
                        data_type=onnx.TensorProto.UINT8,
                        dims=[1],
                        vals=[155])

    #graph.initializer.append(const_mean)

    const_std_r = onnx.helper.make_tensor(name='const_std_r',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[0.022])

    const_std_g = onnx.helper.make_tensor(name='const_std_g',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[0.066])

    const_std_b = onnx.helper.make_tensor(name='const_std_b',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[0.099])                    

    #graph.initializer.append(const_std)

    const_resize = onnx.helper.make_tensor(name='const_resize',
                        data_type=onnx.TensorProto.INT32,
                        dims=[4],
                        vals=[375, 500, 224, 224])

    #graph.initializer.append(const_resize)

    const_crop = onnx.helper.make_tensor(name='const_crop',
                        data_type=onnx.TensorProto.INT32,
                        dims=[4],
                        vals=[0,0,375,500])

    const_control = onnx.helper.make_tensor(name='const_control',
                        data_type=onnx.TensorProto.INT32,
                        dims=[5],
                        vals=[1, 0, 0, 0, 1])   #rgb2bgr, crop_first, norm_first                 

    #graph.initializer.append(const_crop)

    #x = helper.make_tensor_value_info('x', TensorProto.UINT8, [1, 3, 512, 512])
    #y = helper.make_tensor_value_info('y', TensorProto.FLOAT, [1, 3, 224, 224])     

    x = helper.make_tensor_value_info('x', TensorProto.UINT8, [1, 3, 375, 500])
    y = helper.make_tensor_value_info('y', TensorProto.FLOAT, [1, 3, 224, 224])      

    pre_process_node = onnx.helper.make_node(
                    'PreProc',
                    name='preprocess',
                    inputs=['x', 'const_std_r', 'const_std_g', 'const_std_b', 'const_mean_r', 'const_mean_g', 'const_mean_b','const_resize','const_crop', 'const_control'],
                    outputs=['y'],
                    domain='com.metax-tech')

    graph = helper.make_graph(
        [pre_process_node],
        'preproc',
        [
            x
        ],
        [
            y
        ],
        [
            const_std_r,
            const_std_g,
            const_std_b,
            const_mean_r,
            const_mean_g,
            const_mean_b,
            const_resize,
            const_crop,
            const_control
        ]
    )                

    model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 11)])
    
    op_set = model.opset_import.add()
    op_set.domain = 'com.metax-tech'
    op_set.version = 1

    onnx.save(model, './nnaa.onnx')

def make_nnbb():
    const_mean_r = onnx.helper.make_tensor(name='const_mean_r',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[44.11])

    const_mean_g = onnx.helper.make_tensor(name='const_mean_g',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[88.22])

    const_mean_b = onnx.helper.make_tensor(name='const_mean_b',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[155.33])

    #graph.initializer.append(const_mean)

    const_std_r = onnx.helper.make_tensor(name='const_std_r',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[0.022])

    const_std_g = onnx.helper.make_tensor(name='const_std_g',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[0.066])

    const_std_b = onnx.helper.make_tensor(name='const_std_b',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[0.099])                    

    #graph.initializer.append(const_std)

    const_resize = onnx.helper.make_tensor(name='const_resize',
                        data_type=onnx.TensorProto.INT32,
                        dims=[4],
                        vals=[375, 500, 224, 224])

    #graph.initializer.append(const_resize)

    const_crop = onnx.helper.make_tensor(name='const_crop',
                        data_type=onnx.TensorProto.INT32,
                        dims=[4],
                        vals=[0,0,375,500])

    const_control = onnx.helper.make_tensor(name='const_control',
                        data_type=onnx.TensorProto.INT32,
                        dims=[5],
                        vals=[1, 0, 0, 0, 1])   #rgb2bgr, crop_first, norm_first                 

    #graph.initializer.append(const_crop)

    #x = helper.make_tensor_value_info('x', TensorProto.UINT8, [1, 3, 512, 512])
    #y = helper.make_tensor_value_info('y', TensorProto.FLOAT, [1, 3, 224, 224])     

    x = helper.make_tensor_value_info('x', TensorProto.UINT8, [1, 3, 375, 500])
    y = helper.make_tensor_value_info('y', TensorProto.FLOAT, [1, 3, 224, 224])      

    pre_process_node = onnx.helper.make_node(
                    'PreProc',
                    name='preprocess',
                    inputs=['x', 'const_std_r', 'const_std_g', 'const_std_b', 'const_mean_r', 'const_mean_g', 'const_mean_b','const_resize','const_crop', 'const_control'],
                    outputs=['y'],
                    domain='com.metax-tech')

    graph = helper.make_graph(
        [pre_process_node],
        'preproc',
        [
            x
        ],
        [
            y
        ],
        [
            const_std_r,
            const_std_g,
            const_std_b,
            const_mean_r,
            const_mean_g,
            const_mean_b,
            const_resize,
            const_crop,
            const_control
        ]
    )                

    model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 11)])
    
    op_set = model.opset_import.add()
    op_set.domain = 'com.metax-tech'
    op_set.version = 1

    onnx.save(model, './nnbb.onnx')

def make_pre1():
    const_mean_r = onnx.helper.make_tensor(name='const_mean_r',
                        data_type=onnx.TensorProto.UINT8,
                        dims=[1],
                        vals=[100])

    const_mean_g = onnx.helper.make_tensor(name='const_mean_g',
                        data_type=onnx.TensorProto.UINT8,
                        dims=[1],
                        vals=[100])

    const_mean_b = onnx.helper.make_tensor(name='const_mean_b',
                        data_type=onnx.TensorProto.UINT8,
                        dims=[1],
                        vals=[100])

    #graph.initializer.append(const_mean)

    const_std_r = onnx.helper.make_tensor(name='const_std_r',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[0.0074])

    const_std_g = onnx.helper.make_tensor(name='const_std_g',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[0.0074])

    const_std_b = onnx.helper.make_tensor(name='const_std_b',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[0.0074])                    

    #graph.initializer.append(const_std)

    const_resize = onnx.helper.make_tensor(name='const_resize',
                        data_type=onnx.TensorProto.INT32,
                        dims=[4],
                        vals=[375, 500, 224, 224])

    #graph.initializer.append(const_resize)

    const_crop = onnx.helper.make_tensor(name='const_crop',
                        data_type=onnx.TensorProto.INT32,
                        dims=[4],
                        vals=[0,0,300,300])

    const_control = onnx.helper.make_tensor(name='const_control',
                        data_type=onnx.TensorProto.INT32,
                        dims=[5],
                        vals=[1, 0, 0,0, 1])   #rgb2bgr, crop_first, norm_first                 

    #graph.initializer.append(const_crop)

    #x = helper.make_tensor_value_info('x', TensorProto.UINT8, [1, 3, 512, 512])
    #y = helper.make_tensor_value_info('y', TensorProto.FLOAT, [1, 3, 224, 224])     

    x = helper.make_tensor_value_info('x', TensorProto.UINT8, [1, 1, 375, 1500])
    y = helper.make_tensor_value_info('y', TensorProto.FLOAT, [1, 3, 224, 224])      

    pre_process_node = onnx.helper.make_node(
                    'PreProc',
                    name='preprocess',
                    inputs=['x', 'const_std_r', 'const_std_g', 'const_std_b', 'const_mean_r', 'const_mean_g', 'const_mean_b','const_resize','const_crop', 'const_control'],
                    outputs=['y'],
                    domain='com.metax-tech')

    graph = helper.make_graph(
        [pre_process_node],
        'preproc',
        [
            x
        ],
        [
            y
        ],
        [
            const_std_r,
            const_std_g,
            const_std_b,
            const_mean_r,
            const_mean_g,
            const_mean_b,
            const_resize,
            const_crop,
            const_control
        ]
    )                

    model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 11)])
    
    op_set = model.opset_import.add()
    op_set.domain = 'com.metax-tech'
    op_set.version = 1

    onnx.save(model, './pre4.onnx')

def make_pre_reverse():
    const_mean_r = onnx.helper.make_tensor(name='const_mean_r',
                        data_type=onnx.TensorProto.UINT8,
                        dims=[1],
                        vals=[50])

    const_mean_g = onnx.helper.make_tensor(name='const_mean_g',
                        data_type=onnx.TensorProto.UINT8,
                        dims=[1],
                        vals=[100])

    const_mean_b = onnx.helper.make_tensor(name='const_mean_b',
                        data_type=onnx.TensorProto.UINT8,
                        dims=[1],
                        vals=[200])

    #graph.initializer.append(const_mean)

    const_std_r = onnx.helper.make_tensor(name='const_std_r',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[0.001])

    const_std_g = onnx.helper.make_tensor(name='const_std_g',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[0.001])

    const_std_b = onnx.helper.make_tensor(name='const_std_b',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[0.001])                    

    #graph.initializer.append(const_std)

    const_resize = onnx.helper.make_tensor(name='const_resize',
                        data_type=onnx.TensorProto.INT32,
                        dims=[4],
                        vals=[375, 500, 375, 500])

    #graph.initializer.append(const_resize)

    const_crop = onnx.helper.make_tensor(name='const_crop',
                        data_type=onnx.TensorProto.INT32,
                        dims=[4],
                        vals=[0,0,375,500])

    const_control = onnx.helper.make_tensor(name='const_control',
                        data_type=onnx.TensorProto.INT32,
                        dims=[5],
                        vals=[1, 0, 0, 1, 1])   #rgb2bgr, crop_first, norm_first                 

    #graph.initializer.append(const_crop)

    #x = helper.make_tensor_value_info('x', TensorProto.UINT8, [1, 3, 512, 512])
    #y = helper.make_tensor_value_info('y', TensorProto.FLOAT, [1, 3, 224, 224])     

    x = helper.make_tensor_value_info('x', TensorProto.UINT8, [1, 1, 375, 1500])
    y = helper.make_tensor_value_info('y', TensorProto.FLOAT, [1, 3, 375, 500])      

    pre_process_node = onnx.helper.make_node(
                    'PreProc',
                    name='preprocess',
                    inputs=['x', 'const_std_r', 'const_std_g', 'const_std_b', 'const_mean_r', 'const_mean_g', 'const_mean_b','const_resize','const_crop', 'const_control'],
                    outputs=['y'],
                    domain='com.metax-tech')

    graph = helper.make_graph(
        [pre_process_node],
        'preproc',
        [
            x
        ],
        [
            y
        ],
        [
            const_std_r,
            const_std_g,
            const_std_b,
            const_mean_r,
            const_mean_g,
            const_mean_b,
            const_resize,
            const_crop,
            const_control
        ]
    )                

    model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 11)])
    
    op_set = model.opset_import.add()
    op_set.domain = 'com.metax-tech'
    op_set.version = 1

    onnx.save(model, './pre5.onnx')

def make_pre7():
    const_mean_r = onnx.helper.make_tensor(name='const_mean_r',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[50.123])

    const_mean_g = onnx.helper.make_tensor(name='const_mean_g',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[100.456])

    const_mean_b = onnx.helper.make_tensor(name='const_mean_b',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[200.789])

    #graph.initializer.append(const_mean)

    const_std_r = onnx.helper.make_tensor(name='const_std_r',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[0.001])

    const_std_g = onnx.helper.make_tensor(name='const_std_g',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[0.001])

    const_std_b = onnx.helper.make_tensor(name='const_std_b',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[0.001])                    

    #graph.initializer.append(const_std)

    const_resize = onnx.helper.make_tensor(name='const_resize',
                        data_type=onnx.TensorProto.INT32,
                        dims=[4],
                        vals=[375, 500, 375, 500])

    #graph.initializer.append(const_resize)

    const_crop = onnx.helper.make_tensor(name='const_crop',
                        data_type=onnx.TensorProto.INT32,
                        dims=[4],
                        vals=[0,0,375,500])

    const_control = onnx.helper.make_tensor(name='const_control',
                        data_type=onnx.TensorProto.INT32,
                        dims=[5],
                        vals=[1, 0, 0, 1, 1])   #rgb2bgr, crop_first, norm_first                 

    #graph.initializer.append(const_crop)

    #x = helper.make_tensor_value_info('x', TensorProto.UINT8, [1, 3, 512, 512])
    #y = helper.make_tensor_value_info('y', TensorProto.FLOAT, [1, 3, 224, 224])     

    x = helper.make_tensor_value_info('x', TensorProto.UINT8, [1, 1, 375, 1500])
    y = helper.make_tensor_value_info('y', TensorProto.FLOAT, [1, 3, 375, 500])      

    pre_process_node = onnx.helper.make_node(
                    'PreProc',
                    name='preprocess',
                    inputs=['x', 'const_std_r', 'const_std_g', 'const_std_b', 'const_mean_r', 'const_mean_g', 'const_mean_b','const_resize','const_crop', 'const_control'],
                    outputs=['y'],
                    domain='com.metax-tech')

    graph = helper.make_graph(
        [pre_process_node],
        'preproc',
        [
            x
        ],
        [
            y
        ],
        [
            const_std_r,
            const_std_g,
            const_std_b,
            const_mean_r,
            const_mean_g,
            const_mean_b,
            const_resize,
            const_crop,
            const_control
        ]
    )                

    model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 11)])
    
    op_set = model.opset_import.add()
    op_set.domain = 'com.metax-tech'
    op_set.version = 1

    onnx.save(model, './pre7.onnx')

def make_rgb_packet():
    const_mean_r = onnx.helper.make_tensor(name='const_mean_r',
                        data_type=onnx.TensorProto.UINT8,
                        dims=[1],
                        vals=[50])

    const_mean_g = onnx.helper.make_tensor(name='const_mean_g',
                        data_type=onnx.TensorProto.UINT8,
                        dims=[1],
                        vals=[100])

    const_mean_b = onnx.helper.make_tensor(name='const_mean_b',
                        data_type=onnx.TensorProto.UINT8,
                        dims=[1],
                        vals=[200])

    #graph.initializer.append(const_mean)

    const_std_r = onnx.helper.make_tensor(name='const_std_r',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[0.011])

    const_std_g = onnx.helper.make_tensor(name='const_std_g',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[0.055])

    const_std_b = onnx.helper.make_tensor(name='const_std_b',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[0.099])                    

    #graph.initializer.append(const_std)

    const_resize = onnx.helper.make_tensor(name='const_resize',
                        data_type=onnx.TensorProto.INT32,
                        dims=[4],
                        vals=[375, 500, 375, 500])

    #graph.initializer.append(const_resize)

    const_crop = onnx.helper.make_tensor(name='const_crop',
                        data_type=onnx.TensorProto.INT32,
                        dims=[4],
                        vals=[0,0,375,500])

    const_control = onnx.helper.make_tensor(name='const_control',
                        data_type=onnx.TensorProto.INT32,
                        dims=[5],
                        vals=[1, 0, 0, 1, 1])   #rgb2bgr, crop_first, norm_first                 

    #graph.initializer.append(const_crop)

    #x = helper.make_tensor_value_info('x', TensorProto.UINT8, [1, 3, 512, 512])
    #y = helper.make_tensor_value_info('y', TensorProto.FLOAT, [1, 3, 224, 224])     

    x = helper.make_tensor_value_info('x', TensorProto.UINT8, [1, 1, 375, 1500])
    y = helper.make_tensor_value_info('y', TensorProto.FLOAT, [1, 3, 375, 500])      

    pre_process_node = onnx.helper.make_node(
                    'PreProc',
                    name='preprocess',
                    inputs=['x', 'const_std_r', 'const_std_g', 'const_std_b', 'const_mean_r', 'const_mean_g', 'const_mean_b','const_resize','const_crop', 'const_control'],
                    outputs=['y'],
                    domain='com.metax-tech')

    graph = helper.make_graph(
        [pre_process_node],
        'preproc',
        [
            x
        ],
        [
            y
        ],
        [
            const_std_r,
            const_std_g,
            const_std_b,
            const_mean_r,
            const_mean_g,
            const_mean_b,
            const_resize,
            const_crop,
            const_control
        ]
    )                

    model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 11)])
    
    op_set = model.opset_import.add()
    op_set.domain = 'com.metax-tech'
    op_set.version = 1

    onnx.save(model, './pre6.onnx')

def make_pre_only_crop():
    const_mean_r = onnx.helper.make_tensor(name='const_mean_r',
                        data_type=onnx.TensorProto.UINT8,
                        dims=[1],
                        vals=[0])

    const_mean_g = onnx.helper.make_tensor(name='const_mean_g',
                        data_type=onnx.TensorProto.UINT8,
                        dims=[1],
                        vals=[0])

    const_mean_b = onnx.helper.make_tensor(name='const_mean_b',
                        data_type=onnx.TensorProto.UINT8,
                        dims=[1],
                        vals=[0])

    #graph.initializer.append(const_mean)

    const_std_r = onnx.helper.make_tensor(name='const_std_r',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[1.0])

    const_std_g = onnx.helper.make_tensor(name='const_std_g',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[1.0])

    const_std_b = onnx.helper.make_tensor(name='const_std_b',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[1.0])                    

    #graph.initializer.append(const_std)

    const_resize = onnx.helper.make_tensor(name='const_resize',
                        data_type=onnx.TensorProto.INT32,
                        dims=[4],
                        vals=[375, 500, 224, 224])

    #graph.initializer.append(const_resize)

    const_crop = onnx.helper.make_tensor(name='const_crop',
                        data_type=onnx.TensorProto.INT32,
                        dims=[4],
                        vals=[76,138,224,224])

    const_control = onnx.helper.make_tensor(name='const_control',
                        data_type=onnx.TensorProto.INT32,
                        dims=[5],
                        vals=[0, 0, 0,0, 1])   #rgb2bgr, crop_first, norm_first                 

    #graph.initializer.append(const_crop)

    #x = helper.make_tensor_value_info('x', TensorProto.UINT8, [1, 3, 512, 512])
    #y = helper.make_tensor_value_info('y', TensorProto.FLOAT, [1, 3, 224, 224])     

    x = helper.make_tensor_value_info('x', TensorProto.UINT8, [1, 3, 375, 500])
    y = helper.make_tensor_value_info('y', TensorProto.FLOAT, [1, 3, 224, 224])      

    pre_process_node = onnx.helper.make_node(
                    'PreProc',
                    name='preprocess',
                    inputs=['x', 'const_std_r', 'const_std_g', 'const_std_b', 'const_mean_r', 'const_mean_g', 'const_mean_b','const_resize','const_crop', 'const_control'],
                    outputs=['y'],
                    domain='com.metax-tech')

    graph = helper.make_graph(
        [pre_process_node],
        'preproc',
        [
            x
        ],
        [
            y
        ],
        [
            const_std_r,
            const_std_g,
            const_std_b,
            const_mean_r,
            const_mean_g,
            const_mean_b,
            const_resize,
            const_crop,
            const_control
        ]
    )                

    model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 11)])
    
    op_set = model.opset_import.add()
    op_set.domain = 'com.metax-tech'
    op_set.version = 1

    onnx.save(model, './crop1.onnx')

def make_pre_crop2():
    const_mean_r = onnx.helper.make_tensor(name='const_mean_r',
                        data_type=onnx.TensorProto.UINT8,
                        dims=[1],
                        vals=[33])

    const_mean_g = onnx.helper.make_tensor(name='const_mean_g',
                        data_type=onnx.TensorProto.UINT8,
                        dims=[1],
                        vals=[66])

    const_mean_b = onnx.helper.make_tensor(name='const_mean_b',
                        data_type=onnx.TensorProto.UINT8,
                        dims=[1],
                        vals=[99])

    #graph.initializer.append(const_mean)

    const_std_r = onnx.helper.make_tensor(name='const_std_r',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[0.011])

    const_std_g = onnx.helper.make_tensor(name='const_std_g',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[0.055])

    const_std_b = onnx.helper.make_tensor(name='const_std_b',
                        data_type=onnx.TensorProto.FLOAT,
                        dims=[1],
                        vals=[0.099])                    

    #graph.initializer.append(const_std)

    const_resize = onnx.helper.make_tensor(name='const_resize',
                        data_type=onnx.TensorProto.INT32,
                        dims=[4],
                        vals=[375, 500, 224, 224])

    #graph.initializer.append(const_resize)

    const_crop = onnx.helper.make_tensor(name='const_crop',
                        data_type=onnx.TensorProto.INT32,
                        dims=[4],
                        vals=[76,138,224,224])

    const_control = onnx.helper.make_tensor(name='const_control',
                        data_type=onnx.TensorProto.INT32,
                        dims=[5],
                        vals=[0, 0, 0,0, 1])   #rgb2bgr, crop_first, norm_first                 

    #graph.initializer.append(const_crop)

    #x = helper.make_tensor_value_info('x', TensorProto.UINT8, [1, 3, 512, 512])
    #y = helper.make_tensor_value_info('y', TensorProto.FLOAT, [1, 3, 224, 224])     

    x = helper.make_tensor_value_info('x', TensorProto.UINT8, [1, 3, 375, 500])
    y = helper.make_tensor_value_info('y', TensorProto.FLOAT, [1, 3, 224, 224])      

    pre_process_node = onnx.helper.make_node(
                    'PreProc',
                    name='preprocess',
                    inputs=['x', 'const_std_r', 'const_std_g', 'const_std_b', 'const_mean_r', 'const_mean_g', 'const_mean_b','const_resize','const_crop', 'const_control'],
                    outputs=['y'],
                    domain='com.metax-tech')

    graph = helper.make_graph(
        [pre_process_node],
        'preproc',
        [
            x
        ],
        [
            y
        ],
        [
            const_std_r,
            const_std_g,
            const_std_b,
            const_mean_r,
            const_mean_g,
            const_mean_b,
            const_resize,
            const_crop,
            const_control
        ]
    )                

    model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 11)])
    
    op_set = model.opset_import.add()
    op_set.domain = 'com.metax-tech'
    op_set.version = 1

    onnx.save(model, './crop2.onnx')


def make_add_test():
    input_shape = [1,3,9,9]
    output_shape = [1,3,81]

    addB = np.random.ranf(1*3*9*9).astype(np.float32)
    B = helper.make_tensor('B', TensorProto.FLOAT, input_shape, addB)

    X = helper.make_tensor_value_info('X', TensorProto.FLOAT, input_shape)
    Z = helper.make_tensor_value_info('Z', TensorProto.FLOAT, input_shape)

    N = helper.make_tensor_value_info('N', TensorProto.FLOAT, output_shape)

    shape = np.array([1,3,81], dtype=np.int64)
    shapeB = helper.make_tensor('shapeB', TensorProto.INT64, [3], shape)
    
    node_add = helper.make_node(
        'Add', # node name
        ['X', 'B'],
        ['Z']  # outputs
        )

    node_max = helper.make_node(
        'Reshape', # node name
        ['Z', 'shapeB'],
        ['N']  # outputs
        )    

    graph_def = helper.make_graph(
        [node_add, node_max],
        'test_add_mode',
        [X], # graph inputs
        [N], # graph outputs
        initializer=[B, shapeB],
    )
    
    mode_def = helper.make_model(graph_def, opset_imports=[helper.make_opsetid("", 11)])
    mode_def.ir_version = 7
    onnx.checker.check_model(mode_def)
    onnx.save(mode_def, "./add_reshape.onnx")

def make_add_reshape_conv2d():
    input_shape = [1,3,9,9]
    output_shape = [1,3,3, 27]

    addB = np.random.ranf(1*3*9*9).astype(np.float32)
    B = helper.make_tensor('B', TensorProto.FLOAT, input_shape, addB)

    X = helper.make_tensor_value_info('X', TensorProto.FLOAT, input_shape)
    Z = helper.make_tensor_value_info('Z', TensorProto.FLOAT, input_shape)

    N = helper.make_tensor_value_info('N', TensorProto.FLOAT, output_shape)

    shape = np.array([1,3,3,27], dtype=np.int64)
    shapeB = helper.make_tensor('shapeB', TensorProto.INT64, [4], shape)
    
    node_add = helper.make_node(
        'Add', # node name
        ['X', 'B'],
        ['Z']  # outputs
        )

    node_max = helper.make_node(
        'Reshape', # node name
        ['Z', 'shapeB'],
        ['N']  # outputs
        )    

    '''
    graph_def = helper.make_graph(
        [node_add, node_max],
        'test_add_mode',
        [X], # graph inputs
        [N], # graph outputs
        initializer=[B, shapeB],
    )
    '''

def make_add_reshape_pool():
    input_shape = [1,3,4,196]
    output_shape = [1,3,28,28]

    addB = np.random.ranf(1*3*4*196).astype(np.float32)
    B = helper.make_tensor('B', TensorProto.FLOAT, input_shape, addB)

    X = helper.make_tensor_value_info('X', TensorProto.FLOAT, input_shape)
    Z = helper.make_tensor_value_info('Z', TensorProto.FLOAT, input_shape)

    N = helper.make_tensor_value_info('N', TensorProto.FLOAT, output_shape)

    shape = np.array([1,3,28,28], dtype=np.int64)
    shapeB = helper.make_tensor('shapeB', TensorProto.INT64, [4], shape)
    
    node_add = helper.make_node(
        'Add', # node name
        ['X', 'B'],
        ['Z']  # outputs
        )

    node_max = helper.make_node(
        'Reshape', # node name
        ['Z', 'shapeB'],
        ['N']  # outputs
        )    

#########################
    output_shape = [1,3,14,14]
    Y = helper.make_tensor_value_info('Y', TensorProto.FLOAT, output_shape)
    
    node_def = helper.make_node(
        'MaxPool', # node name
        ['N'],
        ['Y'], # outputs
        ceil_mode = 1,
        kernel_shape = [3,3],
        pads = [0,0,0,0],
        strides=[2,2]
        )

    graph_def = helper.make_graph(
        [node_add, node_max, node_def],
        'test_pool_node',
        [X], # graph inputs
        [Y], # graph outputs
        initializer=[B, shapeB],
    )
###############################

    mode_def = helper.make_model(graph_def, opset_imports=[helper.make_opsetid("", 11)])
    mode_def.ir_version = 7
    onnx.checker.check_model(mode_def)
    onnx.save(mode_def, "./add_reshape_pool.onnx")

if __name__ == "__main__":
    #make_nn6a()
    make_pre7()